package com.zboot.zbootadmin.common.utils;

import com.alibaba.fastjson.JSONObject;
import com.zboot.zbootadmin.common.constant.HttpStatus;
import com.zboot.zbootadmin.common.domain.ResponseData;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.FillPatternType;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.xssf.streaming.SXSSFCell;
import org.apache.poi.xssf.streaming.SXSSFRow;
import org.apache.poi.xssf.streaming.SXSSFSheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

/**
 * @Author: zyt
 * @Description: excle工具类
 * @Date: Created in 14:57 2020/3/29
 */
@Slf4j
public class ExcelUtils<T> {


    public ExcelUtils() {
    }

    public  SXSSFWorkbook getTemplateWorkBook(String[] titles,String sheetName) throws IOException {
        SXSSFCell sxssfCell = null;
        SXSSFWorkbook sxssfWorkbook = new SXSSFWorkbook();
        SXSSFSheet sxssfSheet = sxssfWorkbook.createSheet(sheetName);
        sxssfSheet.setDefaultColumnWidth(21);
        SXSSFRow sxssfRow = sxssfSheet.createRow(0);
        for (int i = 0;i<titles.length;i++) {
            sxssfCell = sxssfRow.createCell(i);
            sxssfCell.setCellType(CellType.STRING);
            sxssfCell.setCellValue(titles[i]);
            this.setCellStyle(sxssfWorkbook,sxssfCell);
            this.setFont(sxssfWorkbook);
        }

        return  sxssfWorkbook;
    }

    public void exportTemplate (HttpServletResponse response, SXSSFWorkbook sxssfWorkbook) throws IOException {

        response.setContentType("application/vnd.ms-excel;charset=UTF-8");
        response.setHeader("Content-disposition", "attachment;filename=" + UUID.randomUUID().toString());
        ServletOutputStream outputStream = response.getOutputStream();
        try {
            sxssfWorkbook.write(outputStream);
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            outputStream.flush();
            outputStream.close();
        }


    }

    public void setCellStyle (SXSSFWorkbook sxssfWorkbook,SXSSFCell sxssfCell) {
        CellStyle cellStyle = sxssfWorkbook.createCellStyle();
        cellStyle.setFillForegroundColor(IndexedColors.CORNFLOWER_BLUE.getIndex());
        cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
        sxssfCell.setCellStyle(cellStyle);
    }

    public void setFont(SXSSFWorkbook sxssfWorkbook) {
         sxssfWorkbook.createFont().setColor((short) 0);
    }

    public <T>List<T> importUser (MultipartFile multipartFile, String[] properties, Class<T> clazz) {
        List<T> excelValue = new ArrayList<>();
        DecimalFormat df = new DecimalFormat("0");
        try {
            XSSFRow row = null;
            InputStream inputStream =  multipartFile.getInputStream();
            XSSFWorkbook workbook = new XSSFWorkbook(inputStream);
            XSSFSheet sheet = workbook.getSheetAt(0);
            // 获取总行数
            int lastRowNum = sheet.getLastRowNum();
            for (int i=1;i<=lastRowNum;i++) {
                row = sheet.getRow(i);
                T t = clazz.newInstance();
                for (int j=0;j<properties.length;j++) {
                    String setMethod = ReflectionUtils.getSetMethod(properties[j]);
                    String data = row.getCell(j).toString();
                    ReflectionUtils.setValue(clazz,t,setMethod,data);
                }
                excelValue.add(t);
            }
            workbook.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return excelValue;
    }

    public  void downExcel(String[] titles, List<T> data, HttpServletResponse response, Class<T> clazz, String[] properties){
        try {
            response.setContentType("application/octet-stream;charset=utf-8");
            String uuid = UUID.randomUUID().toString();
            String fileName = uuid+".xlsx";
            response.setHeader("Content-disposition", "attachment;fileName="+ URLEncoder.encode(fileName, "utf-8"));
            ServletOutputStream outputStream = response.getOutputStream();
            SXSSFWorkbook  sxssfWorkbook = new SXSSFWorkbook();
            SXSSFSheet hssfSheet = sxssfWorkbook.createSheet("sheet1");
            SXSSFRow sxssfRow = hssfSheet.createRow(0);
            hssfSheet.setDefaultColumnWidth(21);
            SXSSFCell sxssfCell ;
            for (int i=0;i<titles.length;i++) {
                sxssfCell = sxssfRow.createCell(i);
                sxssfCell.setCellValue(titles[i]);
            }

            for (int i=0;i<data.size();i++) {
                sxssfRow = hssfSheet.createRow(i+1);
                T t = data.get(i);
               for (int j=0;j<properties.length;j++) {
                   String getMethod = ReflectionUtils.getGetMethod(properties[j]);
                   Object value = ReflectionUtils.getValue(clazz,t,getMethod);
                   sxssfRow.createCell(j).setCellValue(value.toString());
               }
            }
            try {
                sxssfWorkbook.write(outputStream);
                outputStream.flush();
                outputStream.close();
            } catch (Exception e) {
                e.printStackTrace();
            }

        }catch (Exception e) {
            e.printStackTrace();
        }

    }

    /**
     * @param src 源字符串
     * @return 字符串，将src的第一个字母转换为大写，src为空时返回null
     */
    private String change(String src) {
        if (src != null) {
            StringBuilder stringBuilder = new StringBuilder(src);
            stringBuilder.setCharAt(0, Character.toUpperCase(stringBuilder.charAt(0)));
            return stringBuilder.toString();
        } else {
            return null;
        }
    }

}
